﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Liolikas.GameMenu;
using Liolikas.GameBoard;
using Liolikas.GameObjects;
using Liolikas.Scores;
using System.Threading;
namespace Liolikas.LiolikasGame
{
    class Renderer
    {
        static public String HORIZONTAL_BORDER = "#";
        static public String VETICAL_BORDER = "#";
        static public ConsoleColor BORDER_COLOR = ConsoleColor.Blue;
        static public ConsoleColor BORDER_BACKGROUND_COLOR = ConsoleColor.Black;
        static public String SCORE_TITLE = "SCORE: ";
        static public String LOADING_MESSAGE = "LOADING...";
        

        public static void InitBoard(){
             Console.Clear();
             Console.BackgroundColor = BORDER_BACKGROUND_COLOR;
             Console.ForegroundColor = BORDER_COLOR;
             DrawHorizontalBorder(true);
             for (int h = 0; h < Board.BOARD_HEIGHT; h++)
             {
                 Console.Write(VETICAL_BORDER);
                 Console.SetCursorPosition(Board.BOARD_WIDTH + VETICAL_BORDER.Length, h+1);
                 Console.WriteLine(VETICAL_BORDER);
             }
             DrawHorizontalBorder(false);
             Console.ResetColor();
             Console.WriteLine();
             Console.Write(SCORE_TITLE+"0");
             Console.SetCursorPosition(Board.BOARD_WIDTH / 2 - LOADING_MESSAGE.Length/2 + 2, Board.BOARD_HEIGHT / 2);
             Console.Write(LOADING_MESSAGE);
        }

        private static void DrawHorizontalBorder(Boolean isUpper)
        {
            
            for (int i = 0; i < Board.BOARD_WIDTH + 2; i++)
                Console.Write(HORIZONTAL_BORDER);
            if (isUpper) Console.WriteLine();
            
        }

        internal static void MoveObject(GameObject obj)
        {
            DeleteObject(obj.lastHCoord, obj.lastWCoord, obj.model.Length);
            RenderObject(obj.hCoord, obj.wCoord, obj.model, obj.objectColor, obj.objectBackgroundColor);    
        }

        internal static void DeleteObject(int hCoord,int  wCoord, int  length)
        {
            Console.SetCursorPosition(wCoord+1, hCoord+1);
            for (int i = 0; i < length; i++ )
                Console.Write(" ");
        }

        internal static void RenderObject(int hCoord, int wCoord, String model, ConsoleColor color, ConsoleColor backgroundColor)
        {
            Console.BackgroundColor = backgroundColor;
            Console.ForegroundColor = color;
            Console.SetCursorPosition(wCoord+1, hCoord+1);
            Console.Write(model);
            Console.ResetColor();
        }

        internal static void UpdateScore(int score)
        {
            Console.SetCursorPosition(7,Board.BOARD_HEIGHT+2);
            Console.Write(score);
        }

        internal static void LiolikasCaught()
        {
                Thread.Sleep(50);
                PlayerChar.GetPlayerChar().model = PlayerChar.CAUGHT_MODEL;
                MovePlayerChar();  
        }


        internal static void GameOver(int gameScore, Boolean isHighScore)
        {
            Console.Clear();
            SkipLines(5);
            Console.WriteLine("   _____          __  __ ______    ______      ________ _____  _ ");
            Console.WriteLine("  / ____|   /\\   |  \\/  |  ____|  / __ \\ \\    / /  ____|  __ \\| |");
            Console.WriteLine(" | |  __   /  \\  | \\  / | |__    | |  | \\ \\  / /| |__  | |__) | |");
            Console.WriteLine(" | | |_ | / /\\ \\ | |\\/| |  __|   | |  | |\\ \\/ / |  __| |  _  /| |");
            Console.WriteLine(" | |__| |/ ____ \\| |  | | |____  | |__| | \\  /  | |____| | \\ \\|_|");
            Console.WriteLine("  \\_____/_/    \\_\\_|  |_|______|  \\____/   \\/   |______|_|  \\_(_)");
            SkipLines(2);
            Console.BackgroundColor = PlayerChar.GetPlayerChar().objectBackgroundColor;
            Console.ForegroundColor = PlayerChar.GetPlayerChar().objectColor;
            Console.WriteLine("                                  __");
            Console.WriteLine("                            _    / /");
            Console.WriteLine("                           (_)  | | ");
            Console.WriteLine("                                | | ");
            Console.WriteLine("                            _   | | ");
            Console.WriteLine("                           (_)  | | ");
            Console.WriteLine("                                 \\_\\");
            SkipLines(3);
            Console.ResetColor();
            
            if (isHighScore)
            {
                SkipLines(1);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("                          NEW HIGH SCORE! ");
            }
            SkipLines(1);
            Console.WriteLine("                          Final Score: " + gameScore);
            Console.ResetColor();
            SkipLines(1);
            Console.WriteLine("                Press Enter to exit to the main menu!");
        }

        internal static void RenderMenu(MenuSection curSection){
            Console.Clear();
            SkipLines(5);
            Console.WriteLine("       _      _____ ____  _      _____ _  __           _____ ");
            Console.WriteLine("      | |    |_   _/ __ \\| |    |_   _| |/ /    /\\    / ____|");
            Console.WriteLine("      | |      | || |  | | |      | | | ' /    /  \\  | (___  ");
            Console.WriteLine("      | |      | || |  | | |      | | |  <    / /\\ \\  \\___ \\ ");
            Console.WriteLine("      | |____ _| || |__| | |____ _| |_| . \\  / ____ \\ ____) |");
            Console.WriteLine("      |______|_____\\____/|______|_____|_|\\_\\/_/    \\_\\_____/ ");
            SkipLines(2);
            Console.BackgroundColor = PlayerChar.GetPlayerChar().objectBackgroundColor;
            Console.ForegroundColor = PlayerChar.GetPlayerChar().objectColor;
            Console.WriteLine("                               _____  ");
            Console.WriteLine("                           _  |  __ \\ ");
            Console.WriteLine("                          (_) | |__) |");
            Console.WriteLine("                              |  ___/ ");
            Console.WriteLine("                           _  | |     ");
            Console.WriteLine("                          (_) |_|     ");
            SkipLines(3);
            Console.ResetColor();
            foreach (MenuSection sec in Menu.GetMenu().GetSections())
            {
                if (sec.Equals(curSection)) Console.Write("                        >> ");
                else Console.Write("                           ");

                Console.WriteLine(sec.name);
                Console.WriteLine();
            }
        }

        internal static void ShowHighScore()
        {
            Console.Clear();
            Console.WriteLine("                     _    _ _____ _____ _    _ ");           
            Console.WriteLine("                    | |  | |_   _/ ____| |  | |");          
            Console.WriteLine("                    | |__| | | || |  __| |__| |");           
            Console.WriteLine("                    |  __  | | || | |_ |  __  |");          
            Console.WriteLine("                    | |  | |_| || |__| | |  | |");           
            Console.WriteLine("                    |_|  |_|_____\\_____|_|  |_|"); 

            Console.WriteLine("              _____  _____ ____  _____  ______  _____    _ ");      
            Console.WriteLine("             / ____|/ ____/ __ \\|  __ \\|  ____|/ ____|  (_)"); 
            Console.WriteLine("            | (___ | |   | |  | | |__) | |__  | (___       "); 
            Console.WriteLine("             \\___ \\| |   | |  | |  _  /|  __|  \\___ \\      ");     
            Console.WriteLine("             ____) | |___| |__| | | \\ \\| |____ ____) |   _ "); 
            Console.WriteLine("            |_____/ \\_____\\____/|_|  \\_\\______|_____/   (_) "); 
            SkipLines(2);
            int i = 1;
            Console.WriteLine("                  | Rank: | Result: | Date:      |");
            Console.WriteLine("                  |_______|_________|____________|"); 
            Console.WriteLine("                  |       |         |            |");
            
            foreach (Score score in HighScore.GetHightScore().scoreList)
            {
                Console.WriteLine("                  | " + i + ".    | " + score.points.ToString().PadRight(8) 
                    + "| " + score.data.PadRight(11)+"|");
                Console.WriteLine("                  |       |         |            |");
                i++;
            }
            SkipLines(2);
            Console.WriteLine("                Press Enter to exit to the main menu!");
        }

        private static  void SkipLines(int n){
            for (int i = 0; i < n; i++ )
                Console.WriteLine();
        }

        internal static void HideLoadingMessage()
        {
            Console.SetCursorPosition(Board.BOARD_WIDTH / 2 - LOADING_MESSAGE.Length / 2 + 2, Board.BOARD_HEIGHT / 2);
            for (int i = 0; i < LOADING_MESSAGE.Length; i++)
                Console.Write(" ");
        }

        internal static void MovePlayerChar()
        {
            List<int[]> coordinates = new List<int[]>(PlayerChar.GetPlayerChar().outDatedCoordinates);
            foreach (int[] coord in coordinates)
            {
                Renderer.DeleteObject(coord[0], coord[1], PlayerChar.GetPlayerChar().model.Length);
            }
            PlayerChar.GetPlayerChar().outDatedCoordinates = new List<int[]>();
            Renderer.MoveObject(PlayerChar.GetPlayerChar());
        }
    }
}
